home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
tools
/
sharp
/
sxwork3.lzh
/
サンプル応用編
/
簡易ペイント
/
SPAINT.C
< prev
next >
Wrap
Text File
|
1994-03-10
|
11KB
|
397 lines
/******************************************************************************
* spaint.c: ペイント編集の処理関数
******************************************************************************
* Workroom SX-68K Sample Program Copyright 1994 SHARP
*/
#include <string.h>
#include <sxmemory.h> /* メモリマンを利用するときに必要 */
#include <event.h> /* イベントマンを利用するときに必要 */
#include <sxgraph.h> /* グラフ系マネージャを利用するときに必要 */
#include <dialog.h> /* ダイアログマンを利用するときに必要 */
#include "spaint.h" /* このプログラム固有のヘッダファイル */
/******************************************************************************
* setComData(): 登録時の共通データの設定
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* ComData **hcd 登録の共通データハンドル
* 注釈:
* 図形登録時の共通データ部分の設定を行う。
* また、データを登録したハンドルの確保を行う。
*/
void setComData(ComVal *pcv, ComData **hcd)
{
ComData **temp;
/* 図形種別の設定 */
(*hcd)->id = pcv->drawType;
/* 描画色の設定 */
(*hcd)->color = pcv->paletFC;
/* 描画ペンサイズの設定 */
(*hcd)->penSize = pcv->penSize;
/* 描画モードの設定 */
(*hcd)->drawMode = pcv->drawMode;
/* データを登録したハンドルの確保を行う */
/* データが1件も登録されていないとき */
if (pcv->dataCnt == 0 && pcv->data == NULL) {
(*hcd)->next = NULL;
pcv->data = hcd;
/* すでに登録されたデータが存在するとき */
} else {
temp = pcv->data;
pcv->data = hcd;
(*hcd)->next = temp;
}
/* 登録データ数を更新する */
pcv->dataCnt++;
}
/******************************************************************************
* checkRectPos(): レクタングルの座標チェックおよび調整
******************************************************************************
* 引数: Rect *prc チェックするレクタングル座標へのポインタ
* 注釈:
* レクタングルの各座標をpt1がレクタングルの左上角にpt2がレクタングルの右
* 下角の座標になるように調整を行う。
*/
void checkRectPos(Rect *prc)
{
short save;
/* topがbottomより大きいときは入れ換える */
if (prc->d.top > prc->d.bottom) {
save = prc->d.top;
prc->d.top = prc->d.bottom;
prc->d.bottom = save;
}
/* leftがrightより大きいときは入れ換える */
if (prc->d.left > prc->d.right) {
save = prc->d.left;
prc->d.left = prc->d.right;
prc->d.right = save;
}
}
/******************************************************************************
* drawGraphRgn(): ウィンドウ内部の多角形の描画
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 注釈: drawTypeが多角形のときの処理を行う。
*/
void drawGraphRgn(ComVal *pcv)
{
int cnt = pcv->rgnCnt;
/* 多角形の座標入力点数が0のとき */
if (cnt == 0) {
/* 始点をセーブする */
pcv->rgnPoint[cnt] = pcv->downPos;
/* ラバーバンド表示のために始点座標を設定する */
pcv->rbSize.l.l_t = pcv->rgnPoint[cnt].x_y;
/* カウントアップ */
pcv->rgnCnt++;
/* ダブルクリックされたとき */
} else if (pcv->animFlag == 2)
/* 多角形の登録処理を行う */
makeRgn(pcv);
else {
/* 入力された点を設定する */
pcv->rgnPoint[cnt] = pcv->downPos;
pcv->rgnCnt++;
/* 入力された部分の仮表示を行う */
pcv->rbSize.l.r_b = pcv->downPos.x_y;
dispRubberBand(pcv, 1);
/* 次のラバーバンド表示のために始点座標を設定する */
pcv->rbSize.l.l_t = pcv->rgnPoint[cnt].x_y;
/* 入力可能な最終点のとき、ダブルクリックされたものと見なす */
if (cnt == 99) {
DMError(D_CONFIRM, "これ以上の点は入力できません。\r"
"多角形を終了します。");
/* 多角形の登録処理を行う */
makeRgn(pcv);
}
}
}
/******************************************************************************
* makeRgn(): 多角形の登録
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* 注釈: 多角形の登録および描画処理を行う。
*/
void makeRgn(ComVal *pcv)
{
int cnt, errCode;
ComData **hcd;
/* 多角形の仮表示の消去を行う */
dispRubberBand(pcv, 2);
/* ペンサイズの設定 */
GMPenSize(pcv->penSize.x_y);
GMForeColor(pcv->paletFC);
/* データ登録用にメモリを確保する */
hcd = MMChHdlNew(sizeof(ComData));
if (hcd == NULL) {
DMError(D_CONFIRM, "メモリが不足しています。\r"
"データの登録ができません。");
return;
}
/* 空のリージョンを作成する */
(*hcd)->ext.rgn.hdl = GMNewRgn();
if ((*hcd)->ext.rgn.hdl == NULL) {
DMError(D_CONFIRM, "メモリが確保できません。");
return;
}
/* リージョンの記録開始 */
GMOpenRgn();
/* 多角形形の描画 */
/* 表示位置をデータの先頭に設定する */
GMMove(pcv->rgnPoint[0].x_y);
/* データを元に描画を行う */
for (cnt = 1; cnt < pcv->rgnCnt; cnt++)
GMLine(pcv->rgnPoint[cnt].x_y);
/* 始点データと結ぶ */
GMLine(pcv->rgnPoint[0].x_y);
/* リージョンの記録終了 */
errCode = GMCloseRgn((*hcd)->ext.rgn.hdl);
if (errCode < 0) {
DMError(D_CONFIRM, "メモリが不足しています。\r"
"リージョンの記録ができません。");
return;
}
/* 多角形を囲むレクタングルの座標をcomDataのboundsに設定する */
(*hcd)->bounds = (*(*hcd)->ext.rgn.hdl)->bounds;
/* 多角形の点数を設定 */
(*hcd)->ext.rgn.cnt = pcv->rgnCnt;
/* リージョンデータを設定する */
memcpy((*hcd)->ext.rgn.point, pcv->rgnPoint, sizeof(Point) * MAX_RGN_CNT);
/* 共通データの登録処理 */
setComData(pcv, hcd);
/* 入力された多角形の描画を行う */
GMFrameRgn((*hcd)->ext.rgn.hdl);
/* 多角形処理フラグをオフにする */
pcv->rgnCnt = 0;
/* 描画フラグをクリアする */
pcv->animFlag = 0;
}
/******************************************************************************
* drawAll(): ウィンドウ内部全体の描画
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
*/
void drawAll(ComVal *pcv)
{
/* dataを元に描画されたすべての図形の描画を行う */
drawNext(pcv->data);
}
/******************************************************************************
* drawNext(): 現在描画されている図形をすべて描画
******************************************************************************
* 引数: ComData **next 描画図形データのハンドル
*/
void drawNext(ComData **next)
{
ComData **hcd;
/* 一番最初に描画された図形データから描画を行う */
/* 指定図形データのハンドルがNULLならば処理終了 */
if (next == NULL)
return;
hcd = next;
/* 1つ前のデータのハンドルを渡して図形の描画を行う */
drawNext((*hcd)->next);
/* 実際のデータの描画を行う */
drawOne(next);
}
/******************************************************************************
* drawOne(): 指定された図形データの描画
******************************************************************************
* 引数: ComData **data 描画図形データのハンドル
*/
void drawOne(ComData **data)
{
int id, mode;
Rect rc;
ComData **hcd;
/* hcdにハンドルを設定する */
hcd = data;
/* idに図形の種類を取得する */
id = (*hcd)->id;
/* 指定図形データのペンサイズに設定する */
GMPenSize((*hcd)->penSize.x_y);
/* 指定図形データの描画色に設定する */
GMForeColor((*hcd)->color);
/* modeに指定図形データの描画モードを設定する */
mode = (*hcd)->drawMode;
/* 図形の種類が多角形ではないとき */
if (id >= 1 && id <=4) {
/* 描画する座標をrcに設定する */
rc = (*hcd)->bounds;
/* 図形の種類および描画モードによって描画を行う */
drawZukei(id, mode, &rc, (*hcd)->ext.radius.x_y);
/* 多角形のとき */
} else if ((*hcd)->ext.rgn.hdl != NULL) {
/* 描画モードによって多角形の描画を行う */
if (mode == 0)
GMFrameRgn((*hcd)->ext.rgn.hdl);
else
GMFillRgn((*hcd)->ext.rgn.hdl);
}
}
/******************************************************************************
* dispRubberBand(): ラバーバンド表示処理
******************************************************************************
* 引数: ComVal *pcv 共通変数へのポインタ
* int type 描画方法
= 0: 通常のラバーバンド表示
* = 1: ラバーバンド表示の消去のみ
* = 2: 多角形の仮表示消去
*/
void dispRubberBand(ComVal *pcv, int type)
{
int savPenMode;
int cnt;
/* 処理対象外 */
if (type == 0 && (pcv->drawType == 5 && pcv->rgnCnt == 0))
return;
else if (type == 0 && pcv->drawType != 5)
if (pcv->animFlag != 1 || !EMLStill())
return;
/* ペンサイズの設定 */
GMPenSize(LONGWORD(1, 1));
/* 表示色を白に設定 */
GMForeColor(15);
/* ペンモードをXORに設定する */
savPenMode = GMPenMode(G_XOR);
/* 通常のラバーバンド処理のときおよびラバーバンド消去のとき */
if (type == 0 || type == 1) {
/* 画面上にラバーバンド表示がある場合は消去する */
if (pcv->dispRbFlag || type == 1)
drawZukei(pcv->drawType, 0, &pcv->rbSize, pcv->radius.x_y);
/* 通常のラバーバンド処理のとき */
if (type == 0) {
/* ラバーバンド表示フラグをTRUEにする */
if (!pcv->dispRbFlag)
pcv->dispRbFlag = TRUE;
/* マウスポインタの位置を取得する */
pcv->rbSize.l.r_b = EMMSLoc();
/* ラバーバンドの表示を行う */
drawZukei(pcv->drawType, 0, &pcv->rbSize, pcv->radius.x_y);
/* ラバーバンド消去のとき */
/* ラバーバンド表示フラグをFALSEにする */
} else if (pcv->dispRbFlag)
pcv->dispRbFlag = FALSE;
/* 多角形の仮表示消去のとき */
} else {
/* 表示位置をデータの先頭に設定する */
GMMove(pcv->rgnPoint[0].x_y);
/* 格納データを元に仮表示を消去する */
for (cnt = 1; cnt < pcv->rgnCnt; cnt++)
GMLine(pcv->rgnPoint[cnt].x_y);
}
/* ペンモードを元に戻す */
GMPenMode(savPenMode);
/* 描画色を現在の描画色に設定 */
GMForeColor(pcv->paletFC);
/* ペンサイズを現在の描画色に設定 */
GMPenSize(pcv->penSize.x_y);
}
/******************************************************************************
* drawZukei(): 実際の図形表示処理
******************************************************************************
* 引数: int type 描画図形の種類
* int mode 描画モード
* = 0: 枠
* = 1: 塗りつぶし
* Rect *prc 表示に使用する座標
* LPoint radius 半径(ラウンドレクタングルのとき有効)
* 注釈:
* 指定の図形を指定の座標を用いて表示する。
* リージョンについてはラバーバンド表示のときのみ対応。
*/
void drawZukei(int type, int mode, Rect *prc, LPoint radius)
{
Rect rc;
switch (type) {
case 1:
case 5:
/* 直線の描画を行う */
GMMove(prc->l.l_t);
GMLine(prc->l.r_b);
break;
case 2:
case 3:
case 4:
/* prcのデータをrcにコピーする */
rc = *prc;
/* レクタングルの座標をチェックする */
checkRectPos(&rc);
switch (type) {
case 2:
/* 長方形の描画を行う */
if (mode == 0)
/* 描画モードが枠のとき */
GMFrameRect(&rc);
else
/* 描画モードが塗りつぶしのとき */
GMFillRect(&rc);
break;
case 3:
/* 楕円の描画を行う */
if (mode == 0)
/* 描画モードが枠のとき */
GMFrameOval(&rc);
else
/* 描画モードが塗りつぶしのとき */
GMFillOval(&rc);
break;
default:
/* 面取り長方形の描画を行う */
if (mode == 0)
/* 描画モードが枠のとき */
GMFrameRRect(&rc, radius);
else
/* 描画モードが塗りつぶしのとき */
GMFillRRect(&rc, radius);
break;
}
break;
}
}